package com.dragonfly.shutter.controllers;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.dragonfly.shutter.DAOs.UserDAO;
import com.dragonfly.shutter.beans.Message;
import com.dragonfly.shutter.beans.RegisterBean;
import com.dragonfly.shutter.beans.UserDetail;
import com.dragonfly.shutter.services.PasswordService;
import com.dragonfly.shutter.utils.MD5Util;
import com.dragonfly.shutter.utils.SendMail;
import com.dragonfly.shutter.validator.RegisterValidator;
import com.dragonfly.shutter.validator.UserDetailValidator;

/**
 * 注册页面控制器，用于控制注册流程，包括最后填写详细注册信息
 * 
 * @author 金灵杰
 * 
 */
@Controller
@SessionAttributes("validateCode")
public class RegisterController {
	@Autowired
	private UserDAO userDAO;
	
	@Autowired
	private SendMail sendMail;
	
	@Autowired
	private PasswordService passwordService;
	
	@Autowired
	private RegisterValidator registerValidator;		//注册表单验证器
	
	/**
	 * 初始化注册页面，并显示
	 * 
	 * @param model 初始化初始页面中绑定的对象
	 * @return 注册页面的模板名称
	 */
	@RequestMapping(value = "/register.html", method = RequestMethod.GET)
	public String setupRegisterForm(ModelMap model) {
		RegisterBean register = new RegisterBean();
		model.addAttribute("registerBean", register);
		return "register";
	}

	/**
	 * 处理注册表单数据
	 * @param userInfo 用户提交的表单数据
	 * @param request http请求信息
	 * @param model 用户绑定页面对象
	 * @param validateCode 系统生成的验证码
	 * @param result 验证器验证后的结果
	 * @return 表单处理结束后返回的页面
	 */
	@RequestMapping(value = "/register.html", method = RequestMethod.POST)
	public String registerUser(@ModelAttribute("registerBean") RegisterBean userInfo,
			BindingResult result,
			HttpServletRequest request, ModelMap model,
			@ModelAttribute("validateCode") String validateCode) 
	{
		// 验证验证码是否正确
		if (!validateCode.equals(userInfo.getValidateCode().toUpperCase())) 
		{
			result.rejectValue("validateCode", "validator.error", "验证码不正确");
			return "register";
		}
		
		//验证用户名、密码是否符合要求，邮箱是否已经注册
		registerValidator.validate(userInfo, result);
		if(result.hasErrors())
		{
			return "register";
		}
		
		Random rand = new Random();
		String randomCode = Long.toString(Math.abs(rand.nextLong()), 36);
		userInfo.setActiveUrl(new String(randomCode));
		
		//生成注册时间
		userInfo.setRegisterTime(new Date());
		
		//加入数据库
		userInfo.setPassword(MD5Util.EncoderByMd5(userInfo.getPassword().getBytes()));
		userDAO.insertRegisterBean(userInfo);
		
		String path = request.getSession().getServletContext().getRealPath(".");
		try {
			String textTemp = "";
			BufferedReader buffer = new BufferedReader(new FileReader(path + "/emailTemplate/registerEmail.html"));
			String str;
			while((str = buffer.readLine()) != null)
			{
				textTemp += str;
			}
			String activeUrl = "action=register&email=" + URLEncoder.encode(userInfo.getEmail(), "utf-8") 
				+ "&code=" + URLEncoder.encode(userInfo.getActiveUrl(), "utf-8");
			String text = String.format(textTemp, userInfo.getEmail(), request.getScheme() + "://" + request.getRemoteHost() 
					+ ":" + request.getLocalPort() + request.getContextPath() + "/active.html" + "?" + activeUrl);
			sendMail.send(userInfo.getEmail(), "shutter网络相册注册", text);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		Message message = new Message("注册邮件已发送，请接收邮件后完成注册", "注册成功", "index.html");
		model.addAttribute("message", message);
		return "message";
	}
	
	/**
	 * 初始化用户激活表单
	 * @param email 用户所使用的邮箱
	 * @param code 用户验证码
	 * @param model 用于返回视图时使用的模型
	 * @return 返回的视图，如果是非激活用户，则重定向到注册页面。
	 */
	@RequestMapping(value="/active.html", method = RequestMethod.GET, params = "action=register")
	public String setupUserInfoForm(@RequestParam(value = "email", required = false) String email, 
			@RequestParam(value = "code", required = false) String code, ModelMap model)
	{
		if(email == null || code == null)
		{
			return "redirect:/register.html";
		}
		
		UserDetail userDetail = userDAO.selectUserByEmail(email);
		if(userDetail != null && userDetail.getFlagActive().equalsIgnoreCase("actived"))
		{
			Message message = new Message("您已经注册，可直接用该帐号登录", "已经注册", "login.html");
			model.addAttribute("message", message);
			return "message";
		}
		
		if(userDetail != null && userDetail.getActiveUrl().equals(code))
		{
			model.addAttribute("userDetail", userDetail);
			return "userinfo";
		}
		
		return "redirect:/register.html";
	}
	
	/**
	 * 激活用户
	 * @param userDetail 用户详细信息
	 * @param result 表单验证结果
	 * @param model 传递数据的模型
	 * @param oldPassword 用户原密码
	 * @param session 如果激活成功，存放用户id，作为登录用户
	 * @return 处理后返回的视图，激活成功返回信息页面，并重定向到用户主页；激活失败返回用户详细信息输入页面
	 */
	@RequestMapping(value = "/active.html", method = RequestMethod.POST)
	public String activeUser(@ModelAttribute("userDetail") UserDetail userDetail, BindingResult result, 
			ModelMap model, @RequestParam(value="oldPassword", required=false) String oldPassword, HttpSession session)
	{
		//使用验证器验证表单数据
		new UserDetailValidator().validate(userDetail, result);
		if(result.hasErrors())
		{
			return "userinfo";
		}
		
		//用户需要同时修改密码
		if(!userDetail.getPassword().isEmpty() && oldPassword != null)
		{
			if(!passwordService.changePassword(oldPassword, userDetail))
			{
				model.addAttribute("errorPasswordStr", "原密码错误，请重新输入");
				return "userinfo";
			}
		}
		
		//FIXME:需要加入事务处理
		
		userDetail.setFlagActive("actived");
		
		userDAO.updateFlagActive(userDetail);
		userDAO.updateUser(userDetail);
		
		//将用户id放入session，用户不用再次登录
		session.setAttribute("userID", userDetail.getUserID());
		
		Message message = new Message("注册成功，现在返回您的首页", "注册成功", "user.html?userID="+userDetail.getUserID());
		model.addAttribute("message", message);
		return "message";
	}
	
	/**
	 * 设置表单中日期的格式化方法
	 * @param binder 用于绑定表单数据格式化方法
	 */
	@InitBinder
	public void initBinder(WebDataBinder binder)
	{
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
	}
}
